﻿namespace Equinoxe.EZNFC.Library
{
    /// <summary>
    /// Interface for a tag
    /// </summary>
    /// <remarks></remarks>
    public interface INFCTag
    {
        /// <summary>
        /// Gets the tag info.
        /// </summary>
        /// <remarks></remarks>
        TagInfo TagInfo { get; }

        /// <summary>
        /// Gets the tag ID.
        /// </summary>
        /// <remarks></remarks>
        uint TagID { get; }

        /// <summary>
        /// Sends the message.
        /// </summary>
        /// <param name="sendbuffer">The sendbuffer.</param>
        /// <param name="sendbufferlength">The sendbufferlength.</param>
        /// <param name="receivebuffer">The receivebuffer.</param>
        /// <param name="receivebufferlength">The receivebufferlength.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void SendMessage(byte[] sendbuffer, int sendbufferlength, byte[] receivebuffer, int receivebufferlength);

        /// <summary>
        /// Authenticates with a specified key.
        /// </summary>
        /// <param name="keyToUse">The key to use.</param>
        /// <param name="block">The block.</param>
        /// <param name="key">The key.</param>
        /// <param name="keyLength">Length of the key.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void Authenticate(AuthenticatingKey keyToUse, int block, byte[] key, int keyLength);

        /// <summary>
        /// Authenticates  with a specified key.
        /// </summary>
        /// <param name="keyToUse">The key to use.</param>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <param name="key">The key.</param>
        /// <param name="keyLength">Length of the key.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void Authenticate(AuthenticatingKey keyToUse, int sector, int block, byte[] key, int keyLength);

        /// <summary>
        /// Authenticates with a specified key.
        /// </summary>
        /// <param name="keyToUse">The key to use.</param>
        /// <param name="block">The block.</param>
        /// <param name="key">The key.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void Authenticate(AuthenticatingKey keyToUse, int block, string key);


        /// <summary>
        /// Authenticates with a specified key.
        /// </summary>
        /// <param name="keyToUse">The key to use.</param>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <param name="key">The key.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void Authenticate(AuthenticatingKey keyToUse, int sector, int block, string key);
        /// <summary>
        /// Reads a block.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <param name="buffer">The buffer.</param>
        /// <param name="bufferlength">The bufferlength.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void ReadBlock(int block, byte[] buffer, ref int bufferlength);


        /// <summary>
        /// Reads a block.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <param name="buffer">The buffer.</param>
        /// <param name="bufferlength">The bufferlength.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void ReadBlock(int sector, int block, byte[] buffer, ref int bufferlength);
        /// <summary>
        /// Reads a block into a string.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        string ReadBlockString(int block);

        /// <summary>
        /// Reads a block into a string.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        string ReadBlockString(int sector, int block);
        /// <summary>
        /// Writes a block.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <param name="buffer">The buffer.</param>
        /// <param name="bufferlength">The bufferlength.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void WriteBlock(int block, byte[] buffer, ref int bufferlength);

        /// <summary>
        /// Writes a block.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <param name="buffer">The buffer.</param>
        /// <param name="bufferlength">The bufferlength.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void WriteBlock(int sector, int block, byte[] buffer, ref int bufferlength);
        /// <summary>
        /// Writes a string in a block.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void WriteBlockString(int block, string data);


        /// <summary>
        /// Writes a string in a block.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void WriteBlockString(int sector, int block, string data);
        /// <summary>
        /// Reads a value block.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <param name="check">if set to <c>true</c> [check].</param>
        /// <returns></returns>
        /// <remarks></remarks>
        int ReadValueBlock(int block, bool check = false);


        /// <summary>
        /// Reads a value block.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <param name="check">if set to <c>true</c> [check].</param>
        /// <returns></returns>
        /// <remarks></remarks>
        int ReadValueBlock(int sector, int block, bool check = false);
        /// <summary>
        /// Writes a value block.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <param name="value">The value.</param>
        /// <param name="adressblock">The adressblock.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void WriteValueBlock(int block, int value, int adressblock = 255);


        /// <summary>
        /// Writes a value block.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <param name="value">The value.</param>
        /// <param name="adressblock">The adressblock.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void WriteValueBlock(int sector, int block, int value, int adressblock = 255);
        /// <summary>
        /// Increments a value block.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void IncrementValueBlock(int block, int value = 1);


        /// <summary>
        /// Increments a value block.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void IncrementValueBlock(int sector, int block, int value = 1);
        /// <summary>
        /// Decrements a value block.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void DecrementValueBlock(int block, int value = 1);


        /// <summary>
        /// Decrements a value block.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void DecrementValueBlock(int sector, int block, int value = 1);
        /// <summary>
        /// Commits a block operation.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void CommitBlockOperation(int block);

        /// <summary>
        /// Commits a block operation.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void CommitBlockOperation(int sector, int block);
        /// <summary>
        /// Rollbacks a block operation.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void RollbackBlockOperation(int block);

        /// <summary>
        /// Rollbacks a block operation.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="block">The block.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void RollbackBlockOperation(int sector, int block);
        /// <summary>
        /// Copies the value block to another value block.
        /// </summary>
        /// <param name="sourceblock">The source block.</param>
        /// <param name="destinationblock">The destination block.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void CopyValueBlock(int sourceblock, int destinationblock);


        /// <summary>
        /// Copies the value block to another value block.
        /// </summary>
        /// <param name="sourcesector">The source sector.</param>
        /// <param name="sourceblock">The source block.</param>
        /// <param name="destinationsector">The destination sector.</param>
        /// <param name="destinationblock">The destination block.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        void CopyValueBlock(int sourcesector, int sourceblock, int destinationsector, int destinationblock);
        /// <summary>
        /// Logoffs this instance.
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        void Logoff();
    }
}
